import React, { SyntheticEvent } from 'react';

import {
  DataSourcePluginOptionsEditorProps,
  onUpdateDatasourceJsonDataOption,
  onUpdateDatasourceSecureJsonDataOption,
  updateDatasourcePluginJsonDataOption,
  updateDatasourcePluginResetOption,
} from '@grafana/data';
import {
  Alert,
  FieldSet,
  InlineField,
  InlineFieldRow,
  InlineSwitch,
  Input,
  Link,
  SecretInput,
  SecureSocksProxySettings,
} from '@grafana/ui';
import { config } from 'app/core/config';
import { ConnectionLimits } from 'app/features/plugins/sql/components/configuration/ConnectionLimits';
import { TLSSecretsConfig } from 'app/features/plugins/sql/components/configuration/TLSSecretsConfig';
import { useMigrateDatabaseFields } from 'app/features/plugins/sql/components/configuration/useMigrateDatabaseFields';

import { MySQLOptions } from '../types';

export const ConfigurationEditor = (props: DataSourcePluginOptionsEditorProps<MySQLOptions>) => {
  const { options, onOptionsChange } = props;
  const jsonData = options.jsonData;

  useMigrateDatabaseFields(props);

  const onResetPassword = () => {
    updateDatasourcePluginResetOption(props, 'password');
  };

  const onDSOptionChanged = (property: keyof MySQLOptions) => {
    return (event: SyntheticEvent<HTMLInputElement>) => {
      onOptionsChange({ ...options, ...{ [property]: event.currentTarget.value } });
    };
  };

  const onSwitchChanged = (property: keyof MySQLOptions) => {
    return (event: SyntheticEvent<HTMLInputElement>) => {
      updateDatasourcePluginJsonDataOption(props, property, event.currentTarget.checked);
    };
  };

  const WIDTH_SHORT = 15;
  const WIDTH_MEDIUM = 25;
  const WIDTH_LONG = 40;

  return (
    <>
      <FieldSet label="MySQL Connection" width={400}>
        <InlineField labelWidth={WIDTH_SHORT} label="Host">
          <Input
            width={WIDTH_LONG}
            name="host"
            type="text"
            value={options.url || ''}
            placeholder="localhost:3306"
            onChange={onDSOptionChanged('url')}
          ></Input>
        </InlineField>
        <InlineField labelWidth={WIDTH_SHORT} label="Database">
          <Input
            width={WIDTH_LONG}
            name="database"
            value={jsonData.database || ''}
            placeholder="database name"
            onChange={onUpdateDatasourceJsonDataOption(props, 'database')}
          ></Input>
        </InlineField>
        <InlineFieldRow>
          <InlineField labelWidth={WIDTH_SHORT} label="User">
            <Input
              width={WIDTH_SHORT}
              value={options.user || ''}
              placeholder="user"
              onChange={onDSOptionChanged('user')}
            ></Input>
          </InlineField>
          <InlineField labelWidth={WIDTH_SHORT - 5} label="Password">
            <SecretInput
              width={WIDTH_SHORT}
              placeholder="Password"
              isConfigured={options.secureJsonFields && options.secureJsonFields.password}
              onReset={onResetPassword}
              onBlur={onUpdateDatasourceSecureJsonDataOption(props, 'password')}
            ></SecretInput>
          </InlineField>
        </InlineFieldRow>
        <InlineField
          tooltip={
            <span>
              指定数据库会话中使用的时区, e.g. <code>Europe/Berlin</code> 或者
              <code>+02:00</code>. 如果数据库（或数据库主机）的时区为
              设置为UTC以外的其他值。该值是在具有的会话中设置的
              <code>SET time_zone=&apos;...&apos;</code>. 如果将此字段留空，则不会更新时区.
              您可以在MySQL文档中找到更多信息.
            </span>
          }
          label="Session timezone"
          labelWidth={WIDTH_MEDIUM}
        >
          <Input
            width={WIDTH_LONG - 5}
            value={jsonData.timezone || ''}
            onChange={onUpdateDatasourceJsonDataOption(props, 'timezone')}
            placeholder="(default)"
          ></Input>
        </InlineField>
        <InlineFieldRow>
          <InlineField
            labelWidth={WIDTH_MEDIUM}
            tooltip="使用安全json数据中配置的客户端证书启用TLS身份验证."
            htmlFor="tlsAuth"
            label="Use TLS Client Auth"
          >
            <InlineSwitch
              id="tlsAuth"
              onChange={onSwitchChanged('tlsAuth')}
              value={jsonData.tlsAuth || false}
            ></InlineSwitch>
          </InlineField>
          <InlineField
            labelWidth={WIDTH_MEDIUM}
            tooltip="需要验证自签名TLS证书."
            htmlFor="tlsCaCert"
            label="With CA Cert"
          >
            <InlineSwitch
              id="tlsCaCert"
              onChange={onSwitchChanged('tlsAuthWithCACert')}
              value={jsonData.tlsAuthWithCACert || false}
            ></InlineSwitch>
          </InlineField>
        </InlineFieldRow>
        <InlineField
          labelWidth={WIDTH_MEDIUM}
          tooltip="启用时，跳过MySql服务器的TLS证书链和主机名的验证."
          htmlFor="skipTLSVerify"
          label="Skip TLS Verification"
        >
          <InlineSwitch
            id="skipTLSVerify"
            onChange={onSwitchChanged('tlsSkipVerify')}
            value={jsonData.tlsSkipVerify || false}
          ></InlineSwitch>
        </InlineField>
        <InlineField
          labelWidth={WIDTH_MEDIUM}
          tooltip={
            <span>
              如果帐户需要，例如使用PAM定义的帐户，则允许使用明文客户端插件
              身份验证插件。在某些配置中，以明文形式发送密码可能是一个安全问题。
              为了避免密码可能被截获时出现问题，客户端应
              使用保护密码的方法连接到MySQL Server。可能性包括TLS/SSL、IPsec等，
              或专用网络.
            </span>
          }
          htmlFor="allowCleartextPasswords"
          label="Allow Cleartext Passwords"
        >
          <InlineSwitch
            id="allowCleartextPasswords"
            onChange={onSwitchChanged('allowCleartextPasswords')}
            value={jsonData.allowCleartextPasswords || false}
          ></InlineSwitch>
        </InlineField>
      </FieldSet>

      {config.secureSocksDSProxyEnabled && (
        <SecureSocksProxySettings options={options} onOptionsChange={onOptionsChange} />
      )}
      {jsonData.tlsAuth || jsonData.tlsAuthWithCACert ? (
        <FieldSet label="TLS/SSL Auth Details">
          <TLSSecretsConfig
            showCACert={jsonData.tlsAuthWithCACert}
            showKeyPair={jsonData.tlsAuth}
            editorProps={props}
            labelWidth={25}
          ></TLSSecretsConfig>
        </FieldSet>
      ) : null}

      <ConnectionLimits labelWidth={WIDTH_SHORT} options={options} onOptionsChange={onOptionsChange} />

      <FieldSet label="MySQL details">
        <InlineField
          tooltip={
            <span>
              按时间间隔自动分组的下限。例如，建议设置为写入频率
              <code>1m</code> 如果您的数据是每分钟写入一次.
            </span>
          }
          labelWidth={WIDTH_MEDIUM}
          label="Min time interval"
        >
          <Input
            placeholder="1m"
            value={jsonData.timeInterval || ''}
            onChange={onUpdateDatasourceJsonDataOption(props, 'timeInterval')}
          ></Input>
        </InlineField>
      </FieldSet>

      <Alert title="User Permission" severity="info">
        应仅向数据库用户授予对指定数据库的SELECT权限 &amp; 要查询的表.
        Grafana不会验证查询是否安全，因此查询可以包含任何SQL语句。例如,
        诸如 <code>USE otherdb;</code> 和 <code>DROP TABLE user;</code> 将被执行.
        为了防止这种情况，我们 <strong>Highly</strong> 建议您创建具有受限权限的特定MySQL用户.
        查看{' '}
        <Link rel="noreferrer" target="_blank" href="http://docs.grafana.org/features/datasources/mysql/">
          MySQL数据源文档
        </Link>{' '}
        更多信息.
      </Alert>
    </>
  );
};
